package aceim.app.service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import aceim.api.dataentity.ItemAction;
import aceim.api.service.ApiConstants;
import aceim.api.service.ICoreProtocolCallback;
import aceim.api.utils.Logger;
import aceim.api.utils.Logger.LoggerLevel;
import aceim.app.utils.PluginsManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
class ProtocolServicesManager extends PluginsManager {
private final ProtocolListener mListener;
private final Map<String, ProtocolService> mProtocols = new HashMap<String, ProtocolService>();
private final ICoreProtocolCallback.Stub mProtocolCallback;
ProtocolServicesManager(Context context, ICoreProtocolCallback.Stub protocolCallback, ProtocolListener listener) {
super(context, ApiConstants.ACTION_PLUGIN_PROTOCOL);
this.mProtocolCallback = protocolCallback;
this.mListener = listener;
}
void initProtocolServices() {
Logger.log("Init protocol services", LoggerLevel.VERBOSE);
PackageManager packageManager = mContext.getPackageManager();
Intent baseIntent = new Intent(ApiConstants.ACTION_PLUGIN_PROTOCOL);
baseIntent.setFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
List<ResolveInfo> list = packageManager.queryIntentServices(baseIntent, PackageManager.GET_RESOLVED_FILTER);
for (int i = 0; i < list.size(); ++i) {
ResolveInfo info = list.get(i);
ServiceInfo sinfo = info.serviceInfo;
Logger.log("Plugin info: " + sinfo);
initProtocolService(sinfo);
}
}
List<ProtocolService> getProtocolsList() {
return Collections.unmodifiableList(new ArrayList<ProtocolService>(mProtocols.values()));
}
ProtocolService getProtocolServiceByName(String protocolServiceClassName) {
return mProtocols.get(protocolServiceClassName);
}
private void removeProtocolService(String intentSource) {
Logger.log("Remove protocol " + intentSource, LoggerLevel.VERBOSE);
ProtocolService ps = mProtocols.remove(intentSource);
if (ps == null) {
Logger.log("No protocol to fire 'onRemove' for "+intentSource, LoggerLevel.INFO);
return;
} else {
mListener.onAction(ps, ItemAction.DELETED);
}
}
@Override
public void onExit(){
super.onExit();
for (ProtocolService ps : mProtocols.values()) {
ps.onExit();
}
}
@Override
protected void onPackageAdded(String packageName) {
Logger.log("Package added: " + packageName, LoggerLevel.VERBOSE);
/*if (mProtocols.containsKey(packageName)) {
removeProtocolService(packageName);
} */
PackageManager packageManager = mContext.getPackageManager();
ServiceInfo sinfo = null;
try {
PackageInfo info = packageManager.getPackageInfo(packageName, PackageManager.GET_RESOLVED_FILTER);
for (ServiceInfo i : info.services) {
if (i.name.equals(packageName)) {
sinfo = i;
break;
}
}
} catch (Exception e) {
Logger.log(e);
}
if (sinfo == null) {
Logger.log("No protocol service found within a package "+packageName, LoggerLevel.WARNING);
return;
}
boolean newPackage = !mProtocols.containsKey(sinfo.packageName);
mListener.onAction(initProtocolService(sinfo), newPackage ? ItemAction.ADDED : ItemAction.MODIFIED);
}
@Override
protected void onPackageRemoved(String packageName) {
Logger.log("Package removed: " + packageName, LoggerLevel.VERBOSE);
removeProtocolService(packageName);
}
private ProtocolService initProtocolService(ServiceInfo sinfo) {
ProtocolService ps = ProtocolService.create(mContext, sinfo.packageName, sinfo.name, mProtocolCallback, mListener);
mProtocols.put(sinfo.packageName, ps);
return ps;
}
interface ProtocolListener {
void onAction(ProtocolService protocol, ItemAction action);
}
}